﻿using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;

namespace Nomo.TcpModule
{
    /// <summary>
    /// TCP 套接字。
    /// </summary>
    public interface ITcpSocket : IDisposable
    {
        /// <summary>
        /// 套接字。
        /// </summary>
        Socket Socket { get; }

        /// <summary>
        /// 字节包装器。
        /// </summary>
        IPacker Packer { get; }

        /// <summary>
        /// 字节解开包装器。
        /// </summary>
        IUnpacker Unpacker { get; }

        /// <summary>
        /// 是否已连接？
        /// </summary>
        bool IsConnected { get; }

        /// <summary>
        /// 开始连接时。
        /// </summary>
        event Action Connecting;

        /// <summary>
        /// 连接上时。
        /// </summary>
        event Action<bool> Connected;

        /// <summary>
        /// 发送字节数组时。
        /// </summary>
        event Action<int> SendingRawBytes;

        /// <summary>
        /// 发送（经过 <see cref="IPacker.Pack"/> 处理的）消息时。
        /// </summary>
        event Action<byte[]> SendingPackedBytes;

        /// <summary>
        /// 收到字节数组时。
        /// </summary>
        event Action<int> ReceivedRawBytes;

        /// <summary>
        /// 收到（经过 <see cref="IUnpacker.Unpack"/> 处理的）消息时。
        /// </summary>
        event Action<List<byte[]>> ReceivedUnpackedBytes;

        /// <summary>
        /// （被动地）和服务器的连接中断时。
        /// </summary>
        event Action Disconnected;

        /// <summary>
        /// 释放资源时。
        /// </summary>
        event Action Disposing;

        /// <summary>
        /// 连接到网络终结点。
        /// </summary>
        /// <param name="endPoint">要连接到的网络终结点。</param>
        void Connect(IPEndPoint endPoint);

        /// <summary>
        /// 发送数据。
        /// </summary>
        /// <param name="bytes">要发送的数据。</param>
        void Send(byte[] bytes);

        /// <summary>
        /// 关闭连接。
        /// </summary>
        void Disconnect();
    }
}
